package ebedynky.controllers;

import ebedynky.beans.*;
import ebedynky.editors.EditorFactory;
import ebedynky.services.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.validation.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.*;
import org.springframework.validation.*;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

/**
 * @author Ondrej David (davidon1)
 */
@Controller
public class OfferItemController {

    /**
     * Initialises the data binder.
     * @param binder the data binder to be initialised
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        try {
            //        binder.setValidator(new OfferItemValidator());
            binder.registerCustomEditor(Product.class, EditorFactory.getProductIDEditor());
            binder.registerCustomEditor(Offer.class, EditorFactory.getOfferIDEditor());
            binder.registerCustomEditor(Set.class, "boxes", EditorFactory.getBoxIDtoSetEditor());
        } catch (Exception ex) {
            Logger.getLogger(OfferItemController.class.getName()).log(Level.SEVERE, "Binder failed at OfferItemController", ex);
        }
    }

    /**
     * Fetches the offerItem adding page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/offerItemAdd", method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute(new OfferItem());
        model.addAttribute("integer", new Integer(2));
        return "offer/item/createForm";
    }

    /**
     * Extracts the offerItem data from the form,
     * validates them and stores them into the db.
     * @param offerItem data from the form
     * @param result data binding result
     * @return string representing next (success/failure) page location
     */
    @RequestMapping(value = "/offerItemAdd", method = RequestMethod.POST)
    public String create(@Valid OfferItem offerItem, BindingResult result) {
        if (result.hasErrors()) {
            return "offer/item/createForm";
        }
        OfferItemService ois = new OfferItemService();
        ois.addOfferItem(offerItem);
        return "offer/index";
    }

    /**
     * Fetches the offerItem delete page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/offerItemDel", method = RequestMethod.GET)
    public String getDeleteForm(Model model) {
        model.addAttribute(new OfferItem());
        return "offer/item/deleteForm";
    }

    /**
     * Deletes the corresponding offerItem data from the db.
     * @param oi data from the form
     * @param result data binding result
     * @return string representing next (success/failure) page location
     */
    @RequestMapping(value = "/offerItemDel", method = RequestMethod.POST)
    public String delete(@Valid OfferItem oi, BindingResult result) {
        if (result.hasErrors()) {
            return "offer/item/deleteForm";
        }
        OfferItemService ois = new OfferItemService();
        ois.deleteOfferItem(oi.getOfferItemID());
        return "offer/index";
    }

    /**
     * Adds a offeritem map extracted from the db as an attribute to the model.
     * @return Map<Integer, String> map of offerItemIDs and names
     */
    @ModelAttribute("offerItemList")
    protected Map<Integer, String> offerItemData() {
        Map<Integer, String> oiMap = new ConcurrentHashMap<Integer, String>();
        OfferItemService ois = new OfferItemService();
        List<OfferItem> list = ois.getAllOfferItems();
        Iterator<OfferItem> it = list.iterator();
        OfferItem oi;
        while (it.hasNext()) {
            oi = it.next();
            oiMap.put(oi.getOfferItemID(), oi.toString());
        }
        return oiMap;
    }

    /**
     * Adds a product list extracted from the db as an attribute to the model.
     * @return List<Product> list of products
     */
    @ModelAttribute("productList")
    protected List<Product> productData() {
        ProductService ps = new ProductService();
        List<Product> list = ps.getAllProducts();
        return list;
    }

    /**
     * Adds a offeritem map extracted from the db as an attribute to the model.
     * @return Map<Integer, String> map of offerItemIDs and names
     */
    @ModelAttribute("offerList")
    protected Map<Integer, String> offerData() {
        Map<Integer, String> oMap = new ConcurrentHashMap<Integer, String>();
        OfferService os = new OfferService();
        List<Offer> list = os.getAllOffers();
        Iterator<Offer> it = list.iterator();
        Offer o;
        while (it.hasNext()) {
            o = it.next();
            oMap.put(o.getOfferID(), o.toString());
        }
        return oMap;
    }

    /**
     * Adds a box map extracted from the db as an attribute to the model.
     * @return Map<Integer, String> map of offerItemIDs and names
     */
    @ModelAttribute("boxList")
    protected Map<Integer, String> boxData() {
        Map<Integer, String> bMap = new ConcurrentHashMap<Integer, String>();
        BoxService bs = new BoxService();
        List<Box> list = bs.getAllBoxes();
        Iterator<Box> it = list.iterator();
        Box b;
        while (it.hasNext()) {
            b = it.next();
            bMap.put(b.getBoxID(), b.toString());
        }
        return bMap;
    }
}
